package com.love.cloud.admin.service.impl;

import cn.hutool.extra.pinyin.PinyinUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.love.cloud.admin.api.entity.SysDept;
import com.love.cloud.admin.service.AsyncDingTalkService;
import com.love.cloud.admin.service.SysDeptService;
import com.love.cloud.common.core.constant.CommonConstants;
import com.love.cloud.common.zzd.api.GovDingAPICaller;
import com.love.cloud.common.zzd.dto.DingTalkOrgDto;
import com.love.cloud.common.zzd.dto.DivisionsInfoDto;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author hongdongqu
 */
@Service
@Slf4j
public class AsyncDingTalkServiceImpl implements AsyncDingTalkService {
    @Resource
    private GovDingAPICaller govDingAPICaller;
    @Resource
    private SysDeptService sysDeptService;

    @Override
    @Async("taskExecutor")
    public void asyncSuperiorOrgData(String targetOrg, String[] superiorOrgCode) {
        log.info("开始同步浙政钉部门的上级组织"+targetOrg);
        //获取到部门的数据
        QueryWrapper<SysDept> queryWrapper=new QueryWrapper<>();
        queryWrapper.lambda().in(SysDept::getDingTalkId,superiorOrgCode);
        List<SysDept> list = sysDeptService.list(queryWrapper);
        Map<String, List<SysDept>> orgGroupMap = list.stream().collect(Collectors.groupingBy(SysDept::getDingTalkId));
        List<String> orgList= Arrays.asList(superiorOrgCode);
        List<DingTalkOrgDto> orgListByCodes = govDingAPICaller.getOrgListByCodes(orgList);
        //本地部门路径
        String[] localPath=new String[orgListByCodes.size()];
        //浙政钉部门路径
        String[] dingPath=new String[orgListByCodes.size()];
        //浙政钉部门pathname
        String[] dingPathName=new String[orgListByCodes.size()];
        //行政区划编码path
        List<String> divisionCodeList=new ArrayList<>();
        //行政区划编码path名称
        List<String> divisionCodeNameList=new ArrayList<>();
        //目标部门的父级id
        Long parentId=0L;
        List<SysDept> sysDeptList=new ArrayList<>();
        //批量获取到行政区划的名称
        List<String> divisionCodeSearchData = orgListByCodes.stream().map(DingTalkOrgDto::getDivisionCode).collect(Collectors.toList());
        List<DivisionsInfoDto> divisionsInfoList = govDingAPICaller.getDivisionsInfoList(divisionCodeSearchData);
        Map<String, List<DivisionsInfoDto>> divisionsInfoGroup = divisionsInfoList.stream().collect(Collectors.groupingBy(DivisionsInfoDto::getCode));
        //从最上级开始累加
        for (int i=0;i<orgListByCodes.size();i++){
            //获取到行政区划编码,并且追加到有序列表中
            if(StringUtils.isNotEmpty(orgListByCodes.get(i).getDivisionCode())&&!divisionCodeList.contains(orgListByCodes.get(i).getDivisionCode())){
                divisionCodeList.add(orgListByCodes.get(i).getDivisionCode());
                List<DivisionsInfoDto> divisionsInfoDtoList = divisionsInfoGroup.get(orgListByCodes.get(i).getDivisionCode());
                //从浙政钉查询出来的信息中获取到行政区划的中文名称
                if(divisionsInfoDtoList!=null&&divisionsInfoDtoList.size()>0){
                    divisionCodeNameList.add(divisionsInfoDtoList.get(0).getName());
                }
            }
            //如果本地部门中有数据就不添加
            if(orgGroupMap.get(orgListByCodes.get(i).getOrganizationCode())!=null&&orgGroupMap.get(orgListByCodes.get(i).getOrganizationCode()).size()>0){
                localPath[i]=String.valueOf(orgGroupMap.get(orgListByCodes.get(i).getOrganizationCode()).get(0).getId());
                dingPath[i]=orgListByCodes.get(i).getOrganizationCode();
                dingPathName[i]=orgListByCodes.get(i).getOrganizationName();
                if(i==orgListByCodes.size()-1) {
                    parentId=orgGroupMap.get(orgListByCodes.get(i).getOrganizationCode()).get(0).getId();
                }
                continue;
            }
            dingPath[i]=orgListByCodes.get(i).getOrganizationCode();
            dingPathName[i]=orgListByCodes.get(i).getOrganizationName();
            //下发就是未新增的部门
            SysDept sysDept=new SysDept();
            sysDept.setSource(CommonConstants.SOURCE_DING);
            if(i>0){
                sysDept.setParentId(Long.valueOf(localPath[i-1]));
            }else{
                sysDept.setParentId(0L);
            }
            sysDept.setAsyncPathId("/"+ this.getJoinStr(dingPath, "/"));
            sysDept.setAsyncPathName("/"+ this.getJoinStr(dingPathName, "/"));
            sysDept.setName(orgListByCodes.get(i).getOrganizationName());
            //获取到最后一级的新政区划编码
            if(divisionCodeList.size()>0){
                sysDept.setDivision(divisionCodeList.get(divisionCodeList.size()-1));
                String[] path = divisionCodeList.toArray(new String[divisionCodeList.size()]);
                String[] pathName = divisionCodeNameList.toArray(new String[divisionCodeNameList.size()]);
                sysDept.setDivisionPath("/"+ this.getJoinStr(path, "/"));
                sysDept.setDivisionPathName("/"+ this.getJoinStr(pathName, "/"));
                sysDept.setArea(this.getJoinStr(pathName, ","));
            }
            sysDept.setFirstSpell(PinyinUtil.getFirstLetter(orgListByCodes.get(i).getOrganizationName(),""));
            sysDept.setSpell(PinyinUtil.getPinyin(orgListByCodes.get(i).getOrganizationName(),""));
            sysDept.setDingTalkId(orgListByCodes.get(i).getOrganizationCode());
            sysDept.setAsyncPid(orgListByCodes.get(i).getParentCode());
            sysDept.setOrgCode(orgListByCodes.get(i).getInstitutionCode());
            sysDept.setPostalCode(orgListByCodes.get(i).getPostalCode());
            sysDept.setSort(Integer.valueOf(orgListByCodes.get(i).getDisplayOrder()));
            //保存数据
            this.sysDeptService.save(sysDept);
            localPath[i]=String.valueOf(sysDept.getId());
            sysDept.setPath("/"+ this.getJoinStr(localPath, "/"));
            sysDeptList.add(sysDept);
            //获取到最后一个部门的信息
            if(i==orgListByCodes.size()-1){
                parentId=sysDept.getId();
            }
        }
        //批量更新部门信息
        this.sysDeptService.updateBatchById(sysDeptList);
        //新增完上级部门之后,再把目标部门的本地部门路径给更新了
        QueryWrapper<SysDept> updateTargetOrgQuery=new QueryWrapper<>();
        updateTargetOrgQuery.lambda().eq(SysDept::getDingTalkId,targetOrg)
                .last(" limit 1 ");
        SysDept targetDept = this.sysDeptService.getOne(updateTargetOrgQuery);
        //等待五次
        for (int i=0;i<5;i++) {
            if(targetDept==null){
                try {
                    Thread.sleep(5000);
                    targetDept=this.sysDeptService.getOne(updateTargetOrgQuery);
                }catch (Exception ex){
                    ex.printStackTrace();
                }
            }
        }
        if(targetDept!=null){
            targetDept.setPath("/"+ this.getJoinStr(localPath, "/")+"/"+targetDept.getId());
            targetDept.setAsyncPathName("/"+ this.getJoinStr(dingPathName, "/")+"/"+targetDept.getName());
            targetDept.setParentId(parentId);
            //判断是否有设置新政区划编码了
            if(StringUtils.isEmpty(targetDept.getDivision())){
                targetDept.setDivision(divisionCodeList.get(divisionCodeList.size()-1));
                String[] path = divisionCodeList.toArray(new String[divisionCodeList.size()]);
                String[] pathName = divisionCodeNameList.toArray(new String[divisionCodeNameList.size()]);
                targetDept.setDivisionPath("/"+ this.getJoinStr(path, "/"));
                targetDept.setDivisionPathName("/"+ this.getJoinStr(pathName, "/"));
                targetDept.setArea(this.getJoinStr(pathName, ","));
            }
            sysDeptService.updateById(targetDept);
        }
    }

    /**
     * 获取到连接的
     * @return
     */
    private String getJoinStr(String[] t,String joinContent){
        StringBuilder stringBuilder=new StringBuilder();
        for (int i=0;i<t.length;i++) {
            if(StringUtils.isNotEmpty(t[i])){
                if(i>0){
                    stringBuilder.append(joinContent);
                }
                stringBuilder.append(t[i]);
            }else{
                break;
            }
        }
        return stringBuilder.toString();
    }
}
